// 1. 闭包是什么
// -- -- 方法力返回一个方法
// function a() {
//   let a1 = 1;
//   return function() {
//     return a1
//   }
// }

// ------------------------------------
// 2. 闭包存在的意义
// 2.1 延长变量的声明周期
// 2.2 创建私有环境
// let a = '小明' // (已声明) Uncaught SyntaxError: Identifier 'a' has already been declared
// function fn1() {
//   let b = 1
//   console.log(a)
// }
// console.log(b)
// fn1()

// AO = Activity Object

// ------------------------------------

// let name = '小明'
// function fn2() {
//   let name = '小白'
//   function fn3() {
//     // let name = '小红'
//     console.log(name)
//   }
//   fn3()
// }
// fn2()

// ------------------------------------

function outer() {
  let a1 = 111;
  let a2 = 222;
  return function inner() {
    return a1;
  }
}

function fn5() {
  let getInnerData = outer()
  console.log('getInnerData=', getInnerData)
  console.dir(getInnerData)
}
fn5()

// 闭包会常驻内存 => 慎用闭包

// ---------------
// Vue data() 为什么是一个函数？？？？
// data() {
//   return {}
// }


const makeCounter = function () {
  let num = 0;
  function changeBy(val) {
    num += val
  }

  return {
    add: function() {
      changeBy(1)
    },
    reduce: function() {
      changeBy(-1)
    },
    value: function() {
      return num
    }
  }
}

let counter1 = makeCounter()
let counter2 = makeCounter()
console.log('000 counter1', counter1.value())
counter1.add()
counter1.add()
counter2.add()
console.log('111 counter1', counter1.value())
console.log('111 counter2', counter2.value())

// 都有独立的作用域
// 面向对象变成 --- 数据的隐藏和封装